package com.yanqu.road.server.gameplayer.module.activity.tanghulu;

import com.yanqu.road.entity.activity.tanghulu.TangHuLuMakeData;
import com.yanqu.road.entity.activity.tanghulu.TangHuLuScoreInfo;
import com.yanqu.road.entity.activity.tanghulu.TangHuLuUserData;
import com.yanqu.road.entity.config.goods.GoodsInfo;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.logic.bussiness.activity.TangHuLuBusiness;
import com.yanqu.road.pb.activity.TangHuLuProto;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.manger.activity.tanghulu.TangHuLuMgr;
import com.yanqu.road.server.manger.config.GoodsMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class TangHuLuModule extends GeneralModule {

    TangHuLuUserData userData;

    //单局历史数据
    List<TangHuLuMakeData> makeDataList;

    public TangHuLuModule(GamePlayer player) {
        super(player);
    }

    @Override
    public boolean loadData() {
        int activityId = TangHuLuMgr.getShowTimeActivityId();
        if (activityId != 0 && SystemOpenMgr.systemOpen(player, eSystemId.TangHuluActivity.getValue())) {
            userData = TangHuLuBusiness.getUserData(player.getUserId(), activityId);
            makeDataList = TangHuLuBusiness.getMakeData(player.getUserId(), activityId);
            if (userData == null) {
                initUserData();
            }
        }
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return false;
    }

    @Override
    public boolean saveData() {
        if(userData != null){
            if(userData.isInsertOption()){
                TangHuLuBusiness.addTangHuLuUserData(userData);
            }else if(userData.isUpdateOption()){
                TangHuLuBusiness.updateTangHuLuUserData(userData);
            }
        }
        if(makeDataList != null){
            List<TangHuLuMakeData> list = new ArrayList<>(makeDataList);
            for(TangHuLuMakeData data : list){
                if(data.isInsertOption()){
                    TangHuLuBusiness.addTangHuLuMakeData(data);
                }else if(data.isUpdateOption()){
                    TangHuLuBusiness.updateTangHuLuMakeData(data);
                }
            }
        }
        return false;
    }

    public TangHuLuUserData getUserData() {
        return this.userData;
    }

    @Override
    public void afterLogin() {

        syncUserData();
    }

    public void syncUserData(){
        if(this.userData == null){
            return;
        }
        TangHuLuProto.TangHuLuUserDataSyncMsg.Builder syncMsg = TangHuLuProto.TangHuLuUserDataSyncMsg.newBuilder();
        TangHuLuProto.TangHuLuUserDataTemp.Builder dataBuilder = TangHuLuMgr.getUserDataBuilder(this.userData);
        syncMsg.setActivityId(TangHuLuMgr.getShowTimeActivityId());
        syncMsg.setUserData(dataBuilder);
        player.sendPacket(Protocol.U_TANGHULU_ACTIVITY_SYNC_USER_DATA, syncMsg);
    }

    /**
     * 初始玩家数据
     */
    public void initUserData() {
        int showTimeActivityId = TangHuLuMgr.getShowTimeActivityId();
        if(showTimeActivityId == 0){
            return;
        }
        if(userData == null || (userData.getActivityId() != showTimeActivityId && showTimeActivityId > 0)) {
            makeDataList = new ArrayList<>();
            TangHuLuUserData tempUserData = new TangHuLuUserData();
            tempUserData.setActivityId(showTimeActivityId);
            tempUserData.setUserId(player.getUserId());
            tempUserData.setInsertOption();

            userData = tempUserData;
        }
    }

    /**
     * 进入游戏界面(或者初始转盘启动时间)
     */
    public int inGameView(int type) {
        if(userData == null){
            return GameErrorCode.E_ACTIVITY_NO_FOUND;
        }
        TangHuLuMakeData makeData;
        synchronized (userData) {
            makeData = initGameView(type);
        }
        TangHuLuProto.TangHuLuInGameViewRespMsg.Builder respMsg = TangHuLuProto.TangHuLuInGameViewRespMsg.newBuilder();
        TangHuLuProto.TangHuLuMakeDataTemp.Builder makeDataBuilder = TangHuLuMgr.getMakeDataBuilder(makeData);
        respMsg.setRet(0);
        respMsg.setGameData(makeDataBuilder);
        player.sendPacket(Protocol.U_TANGHULU_ACTIVITY_IN_GAME_VIEW, respMsg);
        return 0;
    }

    private TangHuLuMakeData initGameView(int type) {
        TangHuLuMakeData makeData = userData.getCurGame();
        if(type == 1){
            makeData = userData.getSeniorMakeData();
        }
        if (makeData == null) {
            makeData = initTangHuLuMakeData(System.currentTimeMillis(), type);
            if(type == 1){
                userData.setSeniorMakeData(makeData);
            }else if(type == 0){
                userData.setCurGame(makeData);
            }
        }else {
            makeData.setInTime(System.currentTimeMillis());
        }
        userData.setUpdateOption();
        return makeData;
    }

    /**
     * 初始转盘数据
     */
    private TangHuLuMakeData initTangHuLuMakeData(long beginTime, int type) {
        TangHuLuMakeData makeData;
        makeData = new TangHuLuMakeData();
        makeData.setInTime(beginTime);
        makeData.setActivityId(TangHuLuMgr.getShowTimeActivityId());
        makeData.setUserId(player.getUserId());
        makeData.setInsertOption();
        makeData.setType(type);
        //初始闪光点
        makeData.setFlashPoint(TangHuLuMgr.getRandomFlashPoint());
        return makeData;
    }

    /**
     *  单次命中水果
     */
    public int launchFruits(int goodsId, int timeGap, int flyTime, int times, List<TangHuLuProto.TangHuLuPanChangeSpeedTemp> speedList, int type) {
        if(userData == null){
            return GameErrorCode.E_ACTIVITY_NO_FOUND;
        }
        if(userData.getCurGame() == null && type == 0){
            return GameErrorCode.E_TANGHULU_ACTIVITY_GAME_NO_INIT;
        }
        if(userData.getSeniorMakeData() == null && type == 1){
            return GameErrorCode.E_TANGHULU_ACTIVITY_GAME_NO_INIT;
        }
        //倍数
        int multiple = 1;
        TangHuLuMakeData curGame = userData.getCurGame();
        if(type == 1){
            curGame = userData.getSeniorMakeData();
            multiple = TangHuLuMgr.SENIOR_CONSUME_MULTIPLE;
        }
        //时间校验
        //后端gap
        int backendGap = (int)(System.currentTimeMillis() - curGame.getInTime());
        //网络传输消耗或延时超过3500毫秒
        if(backendGap - timeGap > 3500){
            return GameErrorCode.E_TANGHULU_ACTIVITY_LAUNCH_FAILS;
        }
        // 计算位置
        int section = calLaunchSection(timeGap, flyTime, speedList);
        int addition = 0;
        synchronized (userData) {
            //判定是否结束游戏
            Map<Integer, List<Integer>> fruitsMap = curGame.getData();
            //结束当前局(重复命中)
            if(fruitsMap.containsKey(section) && fruitsMap.get(section).size() > 0){
                //水果道具是否充足
                Property consume = PropertyHelper.parseStringToProperty(goodsId + "=1");
                consume.rideProperty(multiple);
                if(!player.getModule(CurrencyModule.class).removeCurrency(consume, eLogMoneyType.Activity, eLogMoneyType.TangHuLuActivityUseGoods)){
                    return GameErrorCode.E_TANGHULU_ACTIVITY_GOODS_NO_ENOUGH;
                }
                TangHuLuMakeData makeData = dealEndLogic(curGame);
                if(makeData == null){
                    return GameErrorCode.E_TANGHULU_ACTIVITY_GAME_NO_INIT;
                }
                //评价得分
                long score = 0;
                TangHuLuScoreInfo scoreInfo = TangHuLuMgr.getScoreInfoByNum(makeData.getData().size());
                addition = getAddition(makeData.getScore(), scoreInfo.getIntegral());
                score += addition;
                //当前局积分
                makeData.setScore(makeData.getScore() + score);
                userData.setTangHuLuNum(userData.getTangHuLuNum() + 1);
                //总积分
                Property scoreProperty = addScoreRewardAndRank(score);

                //客户端响应
                TangHuLuProto.TangHuLuLaunchFruitsRespMsg.Builder respMsg = getLaunchRespBuilder(section, makeData, true);
                respMsg.setTimes(times);
                respMsg.setScoreInfo(TangHuLuMgr.getScoreConfigInfoBuilder(scoreInfo, player));
                respMsg.setAddition(addition);
                player.sendPacket(Protocol.U_TANGHULU_ACTIVITY_LAUNCH_FRUITS, respMsg);
                return 0;
            }else if(!fruitsMap.containsKey(section) || fruitsMap.get(section).size() == 0){
                //水果道具是否充足
                Property consume = PropertyHelper.parseStringToProperty(goodsId + "=1");
                consume.rideProperty(multiple);
                if(!player.getModule(CurrencyModule.class).removeCurrency(consume, eLogMoneyType.Activity, eLogMoneyType.TangHuLuActivityUseGoods)){
                    return GameErrorCode.E_TANGHULU_ACTIVITY_GOODS_NO_ENOUGH;
                }
                //获得积分
                long score = 0;
                //闪光点积分
                if(curGame.getFlashPoint().contains(section)){
                    score += TangHuLuMgr.FLASH_POINT_SCORE * multiple;
                }
                if(fruitsMap.get(section) == null) {
                    fruitsMap.put(section, new ArrayList<>());
                }
                fruitsMap.get(section).add(goodsId);
                //水果积分
                GoodsInfo goodsInfo = GoodsMgr.getGoodsById(goodsId);
                if(goodsInfo != null){
                    score += goodsInfo.getParamList().get(0).longValue() * multiple;
                }

                TangHuLuScoreInfo scoreInfo = null;
                //当前局积分
                curGame.setScore(score + curGame.getScore());
                //确认是否结束当前局
                boolean isEnd = isNormaEnd(curGame);
                if(isEnd){
                    curGame = dealEndLogic(curGame);
                    if(curGame != null) {
                        //评价得分
                        scoreInfo = TangHuLuMgr.getScoreInfoByNum(curGame.getData().size());
                        addition = getAddition(curGame.getScore(), scoreInfo.getIntegral());
                        score += addition;
                        curGame.setScore(addition + curGame.getScore());
                        userData.setTangHuLuNum(userData.getTangHuLuNum() + 1);
                    }
                }
                //总积分
                Property scoreProperty = addScoreRewardAndRank(score);

                TangHuLuProto.TangHuLuLaunchFruitsRespMsg.Builder respMsg = getLaunchRespBuilder(section, curGame, isEnd);
                respMsg.setTimes(times);
                respMsg.setAddition(addition);
                if(scoreInfo != null) {
                    respMsg.setScoreInfo(TangHuLuMgr.getScoreConfigInfoBuilder(scoreInfo, player));
                }else{
                    respMsg.setReward(PropertyHelper.parsePropertyToString(scoreProperty));
                }
                player.sendPacket(Protocol.U_TANGHULU_ACTIVITY_LAUNCH_FRUITS, respMsg);
            }
        }
        return 0;
    }

    /**
     * 快速制作
     */
    public int fastMake(int goodsId) {
        if(userData == null){
            return GameErrorCode.E_ACTIVITY_NO_FOUND;
        }

        Property consume = PropertyHelper.parseStringToProperty(goodsId + "=" + TangHuLuMgr.EQUAL_DIVISION);
        //水果道具是否充足
        if(!player.getModule(CurrencyModule.class).removeCurrency(consume, eLogMoneyType.Activity, eLogMoneyType.TangHuLuActivityUseGoods)){
            return GameErrorCode.E_TANGHULU_ACTIVITY_GOODS_NO_ENOUGH;
        }

        long score = 0;
        GoodsInfo goodsInfo = GoodsMgr.getGoodsById(goodsId);
        if(goodsInfo != null){
            //积分
            score += goodsInfo.getParamList().get(0).longValue() * TangHuLuMgr.EQUAL_DIVISION;
        }
        Property scoreProperty;
        synchronized (userData) {
            int roundNo = makeDataList.size() + 1;
            TangHuLuMakeData makeData = new TangHuLuMakeData();
            makeData.setActivityId(TangHuLuMgr.getShowTimeActivityId());
            makeData.setUserId(player.getUserId());
            makeData.setType(1);  //快速制作
            makeData.setRoundNo(roundNo);
            makeData.setScore(score);
            makeData.setInsertOption();
            //历史数据
            makeDataList.add(makeData);
            //增加总糖葫芦桩
            userData.setTangHuLuNum(userData.getTangHuLuNum() + 1);
            //总积分
            scoreProperty = addScoreRewardAndRank(score);
        }
        TangHuLuProto.TangHuLuFastMakeRespMsg.Builder respMsg = TangHuLuProto.TangHuLuFastMakeRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setUserData(TangHuLuMgr.getUserDataBuilder(userData));
        respMsg.setScore(score);
        //奖励
        respMsg.setReward(PropertyHelper.parsePropertyToString(scoreProperty));
        player.sendPacket(Protocol.U_TANGHULU_ACTIVITY_FAST_MAKE, respMsg);
        return 0;
    }

    /**
     * 主动结束
     */
    public int gameEnd(boolean inShowTime, int type) {
        if(userData == null){
            return GameErrorCode.E_ACTIVITY_NO_FOUND;
        }
        TangHuLuMakeData makeData = null;
        int addition;
        //倍数
        int multiple = 1;
        if(type == 1){
            multiple = TangHuLuMgr.SENIOR_CONSUME_MULTIPLE;
        }
        synchronized (userData) {
            if(type == 0) {
                if (userData.getCurGame() == null) {
                    return GameErrorCode.E_TANGHULU_ACTIVITY_GAME_NO_INIT;
                }
                if (userData.getCurGame().getScore() == 0) {
                    return GameErrorCode.E_TANGHULU_ACTIVITY_GAME_NO_NEED_END;
                }
                makeData = dealEndLogic(userData.getCurGame());
                if (makeData == null) {
                    return GameErrorCode.E_TANGHULU_ACTIVITY_GAME_NO_NEED_END;
                }
            }else if(type == 1){
                if (userData.getSeniorMakeData() == null) {
                    return GameErrorCode.E_TANGHULU_ACTIVITY_GAME_NO_INIT;
                }
                if (userData.getSeniorMakeData().getScore() == 0) {
                    return GameErrorCode.E_TANGHULU_ACTIVITY_GAME_NO_NEED_END;
                }
                makeData = dealEndLogic(userData.getSeniorMakeData());
                if (makeData == null) {
                    return GameErrorCode.E_TANGHULU_ACTIVITY_GAME_NO_NEED_END;
                }
            }

            long score = 0;
            //评价积分
            TangHuLuScoreInfo scoreInfo = TangHuLuMgr.getScoreInfoByNum(makeData.getData().size());
            addition = getAddition(makeData.getScore(), scoreInfo.getIntegral());
            score += addition;
            //当前局积分
            makeData.setScore(score + makeData.getScore());
            //增加总糖葫芦桩
            userData.setTangHuLuNum(userData.getTangHuLuNum() + 1);
            //总积分
            Property scoreProperty = addScoreRewardAndRank(score);
        }
        TangHuLuProto.TangHuLuGameEndRespMsg.Builder respMsg = TangHuLuProto.TangHuLuGameEndRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setUserData(TangHuLuMgr.getUserDataBuilder(userData));
        respMsg.setGameData(TangHuLuMgr.getMakeDataBuilder(makeData));
        respMsg.setAddition(addition);
        respMsg.setEnd(true);
        TangHuLuScoreInfo scoreInfo = TangHuLuMgr.getScoreInfoByNum(makeData.getData().size());
        respMsg.setScoreInfo(TangHuLuMgr.getScoreConfigInfoBuilder(scoreInfo, player));
        if(inShowTime){
            player.sendPacket(Protocol.U_TANGHULU_ACTIVITY_GAME_END_IN_SHOWTIME, respMsg);
        }else {
            player.sendPacket(Protocol.U_TANGHULU_ACTIVITY_GAME_END, respMsg);
        }
        return 0;
    }

    /**
     * 每局结束的评分加成
     */
    private int getAddition(long score, int additionPercent){
        int addition = BigDecimal.valueOf(score).multiply(BigDecimal.valueOf(additionPercent)).divide(BigDecimal.valueOf(100), 0, BigDecimal.ROUND_UP).intValue();
        return addition;
    }

    /**
     * 处理游戏结束
     */
    private TangHuLuMakeData dealEndLogic(TangHuLuMakeData makeData) {
        synchronized (userData){
            if(makeData != null && makeData.getScore() > 0) {
                int roundNo = makeDataList.size() + 1;
                makeData.setRoundNo(roundNo);
                makeData.setInsertOption();
                makeDataList.add(makeData);

                TangHuLuMakeData newMakeData = initTangHuLuMakeData(makeData.getInTime(), makeData.getType());
                if(makeData.getType() == 0) {
                    userData.setCurGame(newMakeData);
                }else {
                    userData.setSeniorMakeData(newMakeData);
                }
                userData.setUpdateOption();
                return makeData;
            }else {
                return null;
            }
        }
    }

    /**
     * 卖糖葫芦（糖葫芦桩转甜蜜值）
     */
    public int turnScore() {
        if(userData == null){
            return GameErrorCode.E_ACTIVITY_NO_FOUND;
        }
        synchronized (userData){
            if (userData.getTangHuLuNum() <= 0) {
                return GameErrorCode.E_TANGHULU_ACTIVITY_NO_TANGHULU_ENOUGH;
            }

            int tangHuLuNum = userData.getTangHuLuNum();
            TangHuLuMakeData turnData = null;
            for (int i = 0; i < tangHuLuNum; i++) {
                //查找是否有未转化的糖葫芦桩
                for (TangHuLuMakeData tempMakeData : makeDataList) {
                    if (!tempMakeData.isTurnScore()) {
                        turnData = tempMakeData;
                        break;
                    }
                }
                if (turnData == null) {
                    break;
                }
                //扣除糖葫芦桩
                userData.setTangHuLuNum(userData.getTangHuLuNum() - 1);
                //当前桩标识已转化
                turnData.setTurnScore(true);
                //记录甜蜜值
                userData.setSweetVal(userData.getSweetVal() + turnData.getScore());
            }

            if (tangHuLuNum != userData.getTangHuLuNum()) {
                userData.setUpdateOption();
                //甜蜜值成就
                player.notifyListener(eGamePlayerEventType.TangHuLuSweetValAchieve.getValue(), userData.getSweetVal());
            }
        }

        TangHuLuProto.TangHuLuTurnScoreRspMsg.Builder respMsg = TangHuLuProto.TangHuLuTurnScoreRspMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setUserData(TangHuLuMgr.getUserDataBuilder(userData));
        player.sendPacket(Protocol.U_TANGHULU_ACTIVITY_TURN_SCORE, respMsg);
        return 0;
    }

    /**
     * 累计积分与冲榜
     */
    private Property addScoreRewardAndRank(long score) {
        //增加总积分
        userData.setTotalScore(userData.getTotalScore() + score);
        userData.setUpdateOption();
        //积分道具获得
        Property scoreProperty = PropertyHelper.parseStringToProperty(TangHuLuMgr.SCORE_GOODS_ID + "=" + score);
        player.getModule(CurrencyModule.class).addCurrency(scoreProperty, eLogMoneyType.Activity, eLogMoneyType.TangHuLuActivityGetScore);
        //排行榜
        player.notifyListener(eGamePlayerEventType.TangHuLuScoreRank.getValue(), userData.getTotalScore());
        player.notifyListener(eGamePlayerEventType.TangHuLuScoreCrossRank.getValue(), userData.getTotalScore());
        return scoreProperty;
    }

    /**
     * 计算命中等份
     */
    private int calLaunchSection(int timeGap, int flyTime, List<TangHuLuProto.TangHuLuPanChangeSpeedTemp> speedList) {
        //double angle = calFixedAngle(timeGap + flyTime, TangHuLuMgr.TURN_ANGLE_PER_SECOND);
        double angle = calVariableLaunchAngle(timeGap + flyTime, speedList);
        angle = angle % 360;
        //插中块
        int section = (int)(Math.floor(angle * TangHuLuMgr.EQUAL_DIVISION / 360));
        section += 1;
        log.info("launch angle {} section {}", angle, section);
        return section;
    }

    /**
     * 计算固定速度的角度
     * @param timeGap 转过的毫秒数
     */
    private double calFixedAngle(int timeGap, int turnSpeedPerSecond) {
        // 转速（每秒转动角度） * 转动时间（毫秒）
        return BigDecimal.valueOf(turnSpeedPerSecond).multiply(BigDecimal.valueOf(timeGap)).
                divide(BigDecimal.valueOf(1000),5, BigDecimal.ROUND_UP).doubleValue();
    }

    /**
     * 计算可变速度的角度
     */
    private double calVariableLaunchAngle(int timeGap, List<TangHuLuProto.TangHuLuPanChangeSpeedTemp> speedList){
        double angle = 0;
        int allTime = timeGap;
        for(int i = speedList.size() - 1; i >= 0; i--){
            TangHuLuProto.TangHuLuPanChangeSpeedTemp temp = speedList.get(i);
            if(allTime >= temp.getGapTime()){
                angle += calFixedAngle(allTime - temp.getGapTime(), temp.getTurnSpeed());
                allTime = allTime - (allTime - temp.getGapTime()) ;
            }
        }
        return  angle;
    }

    /**
     * 是否正常结束
     */
    private boolean isNormaEnd(TangHuLuMakeData data) {
        if(data.getData().size() == TangHuLuMgr.EQUAL_DIVISION){
            return true;
        }else {
            return false;
        }
    }

    private TangHuLuProto.TangHuLuLaunchFruitsRespMsg.Builder getLaunchRespBuilder(int section, TangHuLuMakeData makeData, boolean end) {
        TangHuLuProto.TangHuLuLaunchFruitsRespMsg.Builder respMsg = TangHuLuProto.TangHuLuLaunchFruitsRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setSection(section);
        respMsg.setEnd(end);
        respMsg.setGameData(TangHuLuMgr.getMakeDataBuilder(makeData));
        respMsg.setUserData(TangHuLuMgr.getUserDataBuilder(userData));
        return respMsg;
    }

    public void dailyReset() {

    }

    /**
     * 系统解锁
     */
    public void initSystem() {
        if (userData == null) {
            initUserData();
            syncUserData();
        }
    }
}

